import {Injectable} from '@nestjs/common';
import {CreateApprovalDto} from './dto/create-approval.dto';
import {UpdateApprovalDto} from './dto/update-approval.dto';
import {InjectRepository} from "@nestjs/typeorm";
import {ApprovalRecord} from "./entities/approval.entity";
import {Repository} from "typeorm";
import {ApprovalStatusEnum} from "../../constant/ApprovalStatusEnum";
import {SysUserService} from "../sys_user/sys_user.service";
import {HandleApprovalDto} from "./dto/handle-approval.dto";

type IApprovalData = {
    status: number;
    userId: string[];
}

@Injectable()
export class ApprovalService {
    constructor(@InjectRepository(ApprovalRecord)
                private readonly ApprovalRepository: Repository<ApprovalRecord>,
                private readonly sysUserService: SysUserService
    ) {}

    create(createApprovalDto: CreateApprovalDto) {
        return this.ApprovalRepository.save(createApprovalDto);
    }

    findAll() {
        return this.ApprovalRepository.find();
    }

    findOne(id: string) {
        return this.ApprovalRepository.findOne({
            where: {
                id
            }
        });
    }

    update(id: string, updateApprovalDto: UpdateApprovalDto) {
        return this.ApprovalRepository.update(id, updateApprovalDto);
    }

    remove(id: string) {
        return this.ApprovalRepository.delete(id);
    }

    /**
     * 开启事务,保存所有节点信息
     */
    saveAllNode(nodes: CreateApprovalDto[]) {
        const saveEntity = []
        // 1. 根据前端信息循环生成对象
        nodes.forEach(node => saveEntity.push(this.ApprovalRepository.create(node)));
        const elen = saveEntity.length;
        if (elen > 0) {
            // 2.给 head, trail 赋值
            const headId = saveEntity[0].id;
            const trailId = saveEntity[elen - 1].id
            for (let idx = 0; idx < elen; idx++) {
                // 2.1 给next 赋值
                let next = idx < (elen - 1) ? saveEntity[idx + 1] : null;
                saveEntity[idx].head = headId;
                saveEntity[idx].trail = trailId;
                saveEntity[idx].next = next;
            }
            // 3.开启事务批量保存
            return this.ApprovalRepository.save(saveEntity);
        }


    }

    updateStatus(id: string, status: number) {
        const updateApprovalDto = new UpdateApprovalDto;
        updateApprovalDto.status = status;
        return this.update(id, updateApprovalDto);
    }

    /**
     * 同意节点,将节点状态设置为ApprovalStatusEnum.AGREE(1)
     */
    agreeNode(id: string) {
        return this.updateStatus(id, ApprovalStatusEnum.AGREE)
    }

    /**
     * 撤回,驳回审批结果重置,将相同head的status设置成ApprovalStatusEnum.SUBMIT(0)状态
     * TODO 改进方法, 开启事务,进行批量更新
     */
    restoreStatus(head: string) {
        return this.ApprovalRepository.find({where: {}}).then(value => {
            value.forEach(node => {
                node.status = ApprovalStatusEnum.SUBMIT;
                // TODO 将逐条更新改为批量更新
                this.ApprovalRepository.update(node.id, node).then()
            })
        })
    }


    /**
     * 结束节点, 将尾节点状态设置为ApprovalStatusEnum.REFUSE(2)
     */
    endNode(id: string) {
        return this.updateStatus(id, ApprovalStatusEnum.REFUSE)
    }


    async findByUserId(id: string) {
        // userId 申请的
        // const myPublish =  await this.ApprovalRepository.find({where: {createBy: id, status: 0}})

        // TODO MySQL 支持原生JSON查询
        // userId 审核的
        // 首先不是我提交的
        // TODO 存在越序审核问题
        //const myApprove = await this.ApprovalRepository.query(`SELECT * FROM approval_record WHERE status=0 AND approval_data ->> '$**.userId[*]' like '%${id}%'`)
            // 查询路径是否存在JSON_EXTRACT(json_doc, path[, path] ...)



        const approvalRecordList =   await this.ApprovalRepository.find({where: {status:0}})
        let list = []
        for (const record of approvalRecordList) {
            if(record.createBy == id) {
                // 又一个异步处理
                list.push({...record})

            }else {
                const {approvalData} = record
                let count = 0  // TODO 这个算法比较迷惑
                for (let key=0; key < (approvalData as Array<IApprovalData>).length; key++) {

                    const {status, userId} = approvalData[key]
                    // 审核流程已经被终止了
                    if(status>1){
                        break
                    }
                    if (status == 0 && count++==key && (userId as Array<string>).includes(id)){
                        // 获取发起人用户信息
                        // 我之前的审核人用户信息
                        list.push({...record})
                        break;
                    }
                }

            }

        }
        return list;
    }

    async handleApproval(handleParam: HandleApprovalDto) {
        const {id, status, userId: uid} = handleParam
        try {
            await this.ApprovalRepository.findOne({where:{id}}).then(value => {
                const {approvalData} = value
                try {
                    let count = 0
                    for (let key=0; key < (approvalData as Array<IApprovalData>).length; key++) {
                        const { userId } = approvalData[key]
                        ++count;

                        if ((userId as Array<string>).includes(uid)){
                            approvalData[key].status=status;
                            // 当最后一个status都未1的时候外层的status也为1
                            if(count==3){
                                this.ApprovalRepository.save({...value, status:1})
                            }
                            // console.log(value)
                            this.ApprovalRepository.save(value);
                            break;
                        }
                    }

                }catch (e) {
                    console.log(e)
                }

            })
        }catch (e) {
            console.log(e)
        }


    }
}
